/*
 * 创建日期 2009-11-29
 *
 * 成都天和软件公司
 * 电话：028-85425861
 * 传真：028-85425861-8008
 * 邮编：610041 
 * 版权所有
 */
package  org.fantasy.common.db.mdx;

import  org.fantasy.common.db.DataSourceSupport;
import  org.fantasy.common.db.Callable;
import  org.fantasy.common.exception.DBException;

import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

/**
 *  存储过程调用
 * @author: 王文成
 * @version: 1.0
 * @since 2009-11-29
 */
public class MdxCallable extends DataSourceSupport implements Callable {

    private static Log log = LogFactory.getLog(MdxCallable.class);

    private String procedure;

    public void setProcedure(String procedure) {
        this.procedure = procedure;
    }
    
    public List<Object> call(List<Object> inParams, List<Object> outListType) throws DBException {
        Connection conn = null;
        CallableStatement stmt = null;
        int count = inParams.size();
        try {
            conn = dataSource.getConnection();
            log.debug(MdxUtils.getRuntimeSql(procedure, inParams));
            stmt = conn.prepareCall("{" + procedure + "}");
            for (int i = 0; i < inParams.size(); i++) {
                if (inParams.get(i) instanceof Integer)
                    stmt.setInt(i + 1, ((Integer) inParams.get(i)).intValue());
                else if (inParams.get(i) instanceof Long)
                    stmt.setLong(i + 1, ((Long) inParams.get(i)).longValue());
                else if (inParams.get(i) instanceof String)
                    stmt.setString(i + 1, inParams.get(i).toString());
                else if (inParams.get(i) instanceof java.sql.Date)
                    stmt.setDate(i + 1, (java.sql.Date) inParams.get(i));
                else if (inParams.get(i) instanceof java.sql.Timestamp)
                    stmt.setTimestamp(i + 1, (java.sql.Timestamp) inParams.get(i));
                else if (inParams.get(i) instanceof java.util.Date)
                    stmt.setDate(i + 1, new java.sql.Date(((java.util.Date) inParams.get(i)).getTime()));
                else if (inParams.get(i) instanceof Double)
                    stmt.setDouble(i + 1, ((Double) inParams.get(i)).doubleValue());
                else if (inParams.get(i) instanceof Float)
                    stmt.setFloat(i + 1, ((Float) inParams.get(i)).floatValue());
                /*
                else if (inParams.get(i) instanceof Integer[]) {
                    oracle.sql.ArrayDescriptor desc = oracle.sql.ArrayDescriptor.createDescriptor("INTVARRY", conn);
                    oracle.sql.ARRAY array = new oracle.sql.ARRAY(desc, conn, inParams.get(i));
                    stmt.setArray(i + 1, array);
                } else if (inParams.get(i) instanceof Long[]) {
                    oracle.sql.ArrayDescriptor desc = oracle.sql.ArrayDescriptor.createDescriptor("INTVARRY", conn);
                    oracle.sql.ARRAY array = new oracle.sql.ARRAY(desc, conn, inParams.get(i));
                    stmt.setArray(i + 1, array);
                } else if (inParams.get(i) instanceof String[]) {
                    oracle.sql.ArrayDescriptor desc = oracle.sql.ArrayDescriptor.createDescriptor("STRVARRY", conn);
                    oracle.sql.ARRAY array = new oracle.sql.ARRAY(desc, conn, inParams.get(i));
                    stmt.setArray(i + 1, array);
                } */
                else
                    stmt.setObject(i + 1, inParams.get(i));
            }
            for (int j = 0; j < outListType.size(); j++) {
                stmt.registerOutParameter(count + j + 1, ((Integer) outListType.get(j)).intValue());
            }
            stmt.execute();
            List<Object> outParamList = new ArrayList<Object>();
            for (int k = 0; k < outListType.size(); k++) {
                outParamList.add(stmt.getObject(count + k + 1));
            }
            return outParamList;
        } catch (SQLException ex) {
            log.error(ex);
            throw new DBException(ex.getMessage());
        } finally {
            MdxUtils.closeAll(conn, stmt, null);
        }
    }

    public void call(List<Object> inParams) throws DBException {
        call(inParams, new ArrayList<Object>());
    }

    public void call() throws DBException {
        call(new ArrayList<Object>());
    }
}
